#define RELOCATE

.arch armv7-a
.section .cboot0, "ax"
.arm
.global _x_start
.type _x_start, #function
_x_start:
    adr r3, _bootinfo
    str r4, [r3]
    adr r3, _bootinfo_length
    str r5, [r3]

#ifdef RELOCATE
    adr r3, .L_r_executable_start
    ldr r2, .L_r_executable_start
    add r0, r2, r3 // # r0 holds executable start
    adr r3, .L_r_executable_end
    ldr r2, .L_r_executable_end
    add r1, r2, r3 // # r1 holds executable end

    sub r2, r1, r0 // # r2 hold executable size in bytes

    ldr r3, .L_a_loader_target

    sub r7, r3, r0

    1:
    ldrb r1, [r0], #0
    strb r1, [r3], #0
    add r0, r0, #1
    add r3, r3, #1
    subs r2, r2, #1
    bne 1b

    adr r3, .L_r_N1Main
    ldr r2, .L_r_N1Main
    add r2, r2, r3
    add r2, r2, r7

    mov r0, r4
    mov r1, r5
    mov pc, r2
#else
    adr r3, .L_r_N1Main
    ldr r2, .L_r_N1Main
    add r2, r2, r3
    mov pc, r2
#endif
.size _x_start, . - _x_start
.L_a_args: .word 0x45FFFFF8
.L_a_arg2: .word 0x45FFFFFC
.L_r_executable_start: .word __executable_start - .L_r_executable_start
.L_r_executable_end: .word _end - .L_r_executable_end
# .L_r_N1Main: .word N1Main - .L_r_N1Main
.L_r_N1Main: .word _start - .L_r_N1Main
#ifdef RELOCATE
.L_a_loader_target: .word 0x47000000
#endif
.global _bootinfo
.type _bootinfo, #object
_bootinfo: .word 0
.size _bootinfo, 4

.global _bootinfo_length
.type _bootinfo_length, #object
_bootinfo_length: .word 0
.size _bootinfo_length, 4

.type _boot_lk, #function
_boot_lk:
    ldr r0, .L_a_lk_src_addr
    ldr r1, .L_a_lk_dst_addr
    ldr r2, .L_C_lk_size_4b
    1:
    ldr r3, [r0], #0
    str r3, [r1], #0
    add r0, r0, #4
    add r1, r1, #4
    subs r2, r2, #1
    bne 1b

    dsb
    isb
    ldr r1, .L_a_lk_dst_addr
    mov pc, r1

.size _boot_lk, . - _boot_lk
.L_a_lk_src_addr: .word 0x46100008
.L_a_lk_dst_addr: .word 0x46000000
.L_C_lk_size_4b: .word (1024*1024*5 / 4) // 5 MiB

.section .text, "ax"
.global _jump
.type _jump, #function
_jump:
    mov r4, r1
    mov r5, r2
    mov pc, r0
.size _jump, . - _jump

.global _jump64
.type _jump, #function
// r0 - ATF entry
// r1 - LK argument 1
// r2 - LK argument 2
// r3 - ATF argument pointer
// [sp] - LK entry
_jump64:
    mov r4, r1
    mov r5, r2
    ldr r6, [sp] // LK entry

    mov r7, r3

    //;# ldr r1, =0x10200038 // mcucfg + 0x38
    //;# ldr r1, .Lreset_vector_base
    //;# ldr r1, [r1]
    //;# str r0, [r1]

    mrc p15, 0, r0, c12, c0, 2
    orr r0, r0, #1
    mcr p15, 0, r0, c12, c0, 2
    dsb
    isb

    mrc p15, 0, r0, c12, c0, 2
    orr r0, r0, #2
    mcr p15, 0, r0, c12, c0, 2
    dsb
    isb

    mov r0, #0xC0000000
1:
    wfi
    b 1b
.Lreset_vector_base: .long 0x10200038
.size _jump64, . - _jump64
